www.gusucode.com > VC++ Flash(SWF)文件创建生成Lib库源码+demo-源码程序 > VC++ Flash(SWF)文件创建生成Lib库源码+demo-源码程序/code/SWFLIB_Library/SWFAction.cpp

    // SWFAction.cpp: implementation of the CSWFAction class.
//
//////////////////////////////////////////////////////////////////////

#include "SWFAction.h"


CSWFAction::CSWFAction(bool bButtonAction)
{
	// Init members
	m_ButtonAction = bButtonAction;
	m_NumberActions = 0;
	m_Actions = NULL;
	m_SWFStream = NULL;
	m_SWFStreamLength = 0;
}

CSWFAction::~CSWFAction()
{
	ClearActions();
}

void CSWFAction::Stop()
{
	SWF_ACTIONRECORD action;
	memset(&action, 0, sizeof(SWF_ACTIONRECORD));
	action.ActionCode = 0x07;

	// Add new action to the ActionArray
	m_NumberActions++;
	if (m_Actions == NULL)
		m_Actions = (SWF_ACTIONRECORD*)malloc(sizeof(SWF_ACTIONRECORD));
	else
		m_Actions = (SWF_ACTIONRECORD*)realloc(m_Actions, m_NumberActions*sizeof(SWF_ACTIONRECORD));
	memcpy(&m_Actions[m_NumberActions-1], &action, sizeof(SWF_ACTIONRECORD));
}

void CSWFAction::Play()
{
	SWF_ACTIONRECORD action;
	memset(&action, 0, sizeof(SWF_ACTIONRECORD));
	action.ActionCode = 0x06;

	// Add new action to the ActionArray
	m_NumberActions++;
	if (m_Actions == NULL)
		m_Actions = (SWF_ACTIONRECORD*)malloc(sizeof(SWF_ACTIONRECORD));
	else
		m_Actions = (SWF_ACTIONRECORD*)realloc(m_Actions, m_NumberActions*sizeof(SWF_ACTIONRECORD));
	memcpy(&m_Actions[m_NumberActions-1], &action, sizeof(SWF_ACTIONRECORD));
}

void CSWFAction::NextFrame()
{
	SWF_ACTIONRECORD action;
	memset(&action, 0, sizeof(SWF_ACTIONRECORD));
	action.ActionCode = 0x04;

	// Add new action to the ActionArray
	m_NumberActions++;
	if (m_Actions == NULL)
		m_Actions = (SWF_ACTIONRECORD*)malloc(sizeof(SWF_ACTIONRECORD));
	else
		m_Actions = (SWF_ACTIONRECORD*)realloc(m_Actions, m_NumberActions*sizeof(SWF_ACTIONRECORD));
	memcpy(&m_Actions[m_NumberActions-1], &action, sizeof(SWF_ACTIONRECORD));
}

void CSWFAction::PreviousFrame()
{
	SWF_ACTIONRECORD action;
	memset(&action, 0, sizeof(SWF_ACTIONRECORD));
	action.ActionCode = 0x05;

	// Add new action to the ActionArray
	m_NumberActions++;
	if (m_Actions == NULL)
		m_Actions = (SWF_ACTIONRECORD*)malloc(sizeof(SWF_ACTIONRECORD));
	else
		m_Actions = (SWF_ACTIONRECORD*)realloc(m_Actions, m_NumberActions*sizeof(SWF_ACTIONRECORD));
	memcpy(&m_Actions[m_NumberActions-1], &action, sizeof(SWF_ACTIONRECORD));
}

void CSWFAction::GotoFrame(int frameIndex)
{
	SWF_ACTIONRECORD action;
	memset(&action, 0, sizeof(SWF_ACTIONRECORD));
	action.ActionCode = 0x81;
	action.Length = 2;
	action.ACTION_TYPE.ACTION_GOTO_FRAME.FrameIndex = (USHORT)frameIndex;

	// Add new action to the ActionArray
	m_NumberActions++;
	if (m_Actions == NULL)
		m_Actions = (SWF_ACTIONRECORD*)malloc(sizeof(SWF_ACTIONRECORD));
	else
		m_Actions = (SWF_ACTIONRECORD*)realloc(m_Actions, m_NumberActions*sizeof(SWF_ACTIONRECORD));
	memcpy(&m_Actions[m_NumberActions-1], &action, sizeof(SWF_ACTIONRECORD));
}

void CSWFAction::GotoLabel(UCHAR* frameLabel)
{
	SWF_ACTIONRECORD action;
	memset(&action, 0, sizeof(SWF_ACTIONRECORD));
	action.ActionCode = 0x8C;
	int frameLabelLength = strlen((char*)frameLabel) + 1;
	action.Length = frameLabelLength;

	// Add new action to the ActionArray
	m_NumberActions++;
	if (m_Actions == NULL)
		m_Actions = (SWF_ACTIONRECORD*)malloc(sizeof(SWF_ACTIONRECORD));
	else
		m_Actions = (SWF_ACTIONRECORD*)realloc(m_Actions, m_NumberActions*sizeof(SWF_ACTIONRECORD));
	memcpy(&m_Actions[m_NumberActions-1], &action, sizeof(SWF_ACTIONRECORD));

	m_Actions[m_NumberActions-1].ACTION_TYPE.ACTION_GOTO_LABEL.Label = (UCHAR*)malloc(frameLabelLength*sizeof(UCHAR));
	memcpy(m_Actions[m_NumberActions-1].ACTION_TYPE.ACTION_GOTO_LABEL.Label, frameLabel, frameLabelLength-1);
	m_Actions[m_NumberActions-1].ACTION_TYPE.ACTION_GOTO_LABEL.Label[frameLabelLength-1] = '\0';
}

void CSWFAction::WaitForFrame(int frameIndex, int skipCount)
{
	SWF_ACTIONRECORD action;
	memset(&action, 0, sizeof(SWF_ACTIONRECORD));
	action.ActionCode = 0x8A;
	action.Length = 3;
	action.ACTION_TYPE.ACTION_WAIT_FOR_FRAME.Frame = (USHORT)frameIndex;
	action.ACTION_TYPE.ACTION_WAIT_FOR_FRAME.SkipCount = (UCHAR)skipCount;

	// Add new action to the ActionArray
	m_NumberActions++;
	if (m_Actions == NULL)
		m_Actions = (SWF_ACTIONRECORD*)malloc(sizeof(SWF_ACTIONRECORD));
	else
		m_Actions = (SWF_ACTIONRECORD*)realloc(m_Actions, m_NumberActions*sizeof(SWF_ACTIONRECORD));
	memcpy(&m_Actions[m_NumberActions-1], &action, sizeof(SWF_ACTIONRECORD));
}

void CSWFAction::GetURL(UCHAR* urlString, UCHAR* targetString)
{
	SWF_ACTIONRECORD action;
	memset(&action, 0, sizeof(SWF_ACTIONRECORD));
	action.ActionCode = 0x83;
	int urlLength = strlen((char*)urlString) + 1;
	int targetLength = strlen((char*)targetString) + 1;
	action.Length = urlLength + targetLength;

	// Add new action to the ActionArray
	m_NumberActions++;
	if (m_Actions == NULL)
		m_Actions = (SWF_ACTIONRECORD*)malloc(sizeof(SWF_ACTIONRECORD));
	else
		m_Actions = (SWF_ACTIONRECORD*)realloc(m_Actions, m_NumberActions*sizeof(SWF_ACTIONRECORD));
	memcpy(&m_Actions[m_NumberActions-1], &action, sizeof(SWF_ACTIONRECORD));

	m_Actions[m_NumberActions-1].ACTION_TYPE.ACTION_GET_URL.UrlString = (UCHAR*)malloc(urlLength*sizeof(UCHAR));
	memcpy(m_Actions[m_NumberActions-1].ACTION_TYPE.ACTION_GET_URL.UrlString, urlString, urlLength-1);
	m_Actions[m_NumberActions-1].ACTION_TYPE.ACTION_GET_URL.UrlString[urlLength-1] = '\0';

	m_Actions[m_NumberActions-1].ACTION_TYPE.ACTION_GET_URL.TargetString = (UCHAR*)malloc(targetLength*sizeof(UCHAR));
	memcpy(m_Actions[m_NumberActions-1].ACTION_TYPE.ACTION_GET_URL.TargetString, targetString, targetLength-1);
	m_Actions[m_NumberActions-1].ACTION_TYPE.ACTION_GET_URL.TargetString[targetLength-1] = '\0';
}

void CSWFAction::SetTarget(UCHAR* targetString)
{
	SWF_ACTIONRECORD action;
	memset(&action, 0, sizeof(SWF_ACTIONRECORD));
	action.ActionCode = 0x8B;
	int targetLength = strlen((char*)targetString) + 1;
	action.Length = targetLength;

	// Add new action to the ActionArray
	m_NumberActions++;
	if (m_Actions == NULL)
		m_Actions = (SWF_ACTIONRECORD*)malloc(sizeof(SWF_ACTIONRECORD));
	else
		m_Actions = (SWF_ACTIONRECORD*)realloc(m_Actions, m_NumberActions*sizeof(SWF_ACTIONRECORD));
	memcpy(&m_Actions[m_NumberActions-1], &action, sizeof(SWF_ACTIONRECORD));

	m_Actions[m_NumberActions-1].ACTION_TYPE.ACTION_SET_TARGET.TargetName = (UCHAR*)malloc(targetLength*sizeof(UCHAR));
	memcpy(m_Actions[m_NumberActions-1].ACTION_TYPE.ACTION_SET_TARGET.TargetName, targetString, targetLength-1);
	m_Actions[m_NumberActions-1].ACTION_TYPE.ACTION_SET_TARGET.TargetName[targetLength-1] = '\0';
}

bool CSWFAction::IsButtonAction()
{
	return m_ButtonAction;
}

void CSWFAction::ClearActions()
{
	if (m_Actions != NULL)
	{
		for (int i=0; i<m_NumberActions; i++)
		{
			switch (m_Actions[i].ActionCode)
			{
				// ActionGetURL
				case 0x83:
				{
					if (m_Actions[i].ACTION_TYPE.ACTION_GET_URL.UrlString != NULL)
						free(m_Actions[i].ACTION_TYPE.ACTION_GET_URL.UrlString);
					if (m_Actions[i].ACTION_TYPE.ACTION_GET_URL.TargetString != NULL)
						free(m_Actions[i].ACTION_TYPE.ACTION_GET_URL.TargetString);
				}
				break;
			}
		}

		delete m_Actions;
		m_Actions = NULL;
		m_NumberActions = 0;
	}

	if (m_SWFStream != NULL)
	{
		free(m_SWFStream);
		m_SWFStream = NULL;
		m_SWFStreamLength = 0;
	}
}

UCHAR* CSWFAction::BuildSWFStream()
{
	int i;

	if (m_SWFStream != NULL)
		ClearActions();

	// Calculate ActionArray length
	int actionLength = 0;
	for (i=0; i<m_NumberActions; i++)
	{
		if (m_Actions[i].Length != 0)
			actionLength += (sizeof(UCHAR) + sizeof(USHORT) + m_Actions[i].Length);
		else
			actionLength += sizeof(UCHAR);
	}

	SWF_DOACTION_TAG doActionTag;
	memset(&doActionTag, 0, sizeof(SWF_DOACTION_TAG));
	doActionTag.Header.TagCodeAndLength = (12 << 6) | 0x003F;
	doActionTag.Header.Length = actionLength + sizeof(UCHAR);

	// Allocate memory
	int newLength = sizeof(SWF_RECORDHEADER_LONG) + doActionTag.Header.Length;
	if (m_ButtonAction)
		newLength = actionLength + sizeof(UCHAR);
	m_SWFStream = new UCHAR[newLength];

	// Write header to .SWF stream
	if (!m_ButtonAction)
	{
		newLength = m_SWFStreamLength + sizeof(SWF_RECORDHEADER_LONG);
		memcpy(m_SWFStream+m_SWFStreamLength, &doActionTag.Header, sizeof(SWF_RECORDHEADER_LONG));
		m_SWFStreamLength = newLength;
	}

	// Write ActionArray to .SWF stream
	for (i=0; i<m_NumberActions; i++)
	{
		// Write short ActionRecord to .SWF stream
		memcpy(m_SWFStream+m_SWFStreamLength, &m_Actions[i].ActionCode, sizeof(UCHAR));
		m_SWFStreamLength += sizeof(UCHAR);

		// Write long ActionRecord to .SWF stream
		if (m_Actions[i].Length != 0)
		{
			memcpy(m_SWFStream+m_SWFStreamLength, &m_Actions[i].Length, sizeof(USHORT));
			m_SWFStreamLength += sizeof(USHORT);

			switch (m_Actions[i].ActionCode)
			{
				// ActionGotoFrame
				case 0x81:
				{
					memcpy(m_SWFStream+m_SWFStreamLength, &m_Actions[i].ACTION_TYPE.ACTION_GOTO_FRAME.FrameIndex, sizeof(USHORT));
					m_SWFStreamLength += sizeof(USHORT);
				}
				break;

				// ActionWaitForFrame
				case 0x8A:
				{
					memcpy(m_SWFStream+m_SWFStreamLength, &m_Actions[i].ACTION_TYPE.ACTION_WAIT_FOR_FRAME.Frame, sizeof(USHORT));
					m_SWFStreamLength += sizeof(USHORT);
					memcpy(m_SWFStream+m_SWFStreamLength, &m_Actions[i].ACTION_TYPE.ACTION_WAIT_FOR_FRAME.SkipCount, sizeof(UCHAR));
					m_SWFStreamLength += sizeof(UCHAR);
				}
				break;

				// ActionGetURL
				case 0x83:
				{
					int urlLength = strlen((char*)m_Actions[i].ACTION_TYPE.ACTION_GET_URL.UrlString) + 1;
					int targetLength = strlen((char*)m_Actions[i].ACTION_TYPE.ACTION_GET_URL.TargetString) + 1;
					memcpy(m_SWFStream+m_SWFStreamLength, m_Actions[i].ACTION_TYPE.ACTION_GET_URL.UrlString, urlLength*sizeof(UCHAR));
					m_SWFStreamLength += urlLength;
					memcpy(m_SWFStream+m_SWFStreamLength, m_Actions[i].ACTION_TYPE.ACTION_GET_URL.TargetString, targetLength*sizeof(UCHAR));
					m_SWFStreamLength += targetLength;
				}
				break;

				// ActionGetURL
				case 0x8B:
				{
					int targetLength = strlen((char*)m_Actions[i].ACTION_TYPE.ACTION_SET_TARGET.TargetName) + 1;
					memcpy(m_SWFStream+m_SWFStreamLength, m_Actions[i].ACTION_TYPE.ACTION_SET_TARGET.TargetName, targetLength*sizeof(UCHAR));
					m_SWFStreamLength += targetLength;
				}
				break;

				// ActionGotoLabel
				case 0x8C:
				{
					int labelLength = strlen((char*)m_Actions[i].ACTION_TYPE.ACTION_GOTO_LABEL.Label) + 1;
					memcpy(m_SWFStream+m_SWFStreamLength, m_Actions[i].ACTION_TYPE.ACTION_GOTO_LABEL.Label, labelLength*sizeof(UCHAR));
					m_SWFStreamLength += labelLength;
				}
				break;
			}
		}
	}

	// Write ActionEndTag to .SWF stream
	memcpy(m_SWFStream+m_SWFStreamLength, &doActionTag.ActionEndFlag, sizeof(UCHAR));
	m_SWFStreamLength += sizeof(UCHAR);

	return m_SWFStream;
}

int CSWFAction::GetSWFStreamLength()
{
	return m_SWFStreamLength;
}